package cn.gdchent.springbootsecurity.utils;

import com.dd.plist.NSDictionary;
import com.dd.plist.NSString;
import com.dd.plist.PropertyListParser;

import java.io.*;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class IpaInfoList {
    /**
     * 解压IPA文件，只获取IPA文件的Info.plist文件存储指定位置
     *
     * @param file           zip文件
     * @param unzipDirectory 解压到的目录
     * @throws Exception
     */
    public static File getZipInfo(File file, String unzipDirectory)
            throws Exception {
        // 定义输入输出流对象
        InputStream input = null;
        OutputStream output = null;
        File targetFile = null;
        File unzipFile = null;
        ZipFile zipFile = null;
        try {
            // 创建zip文件对象
            zipFile = new ZipFile(file);
            // 创建本zip文件解压目录
            String name = file.getName().substring(0, file.getName().lastIndexOf("."));
            unzipFile = new File(unzipDirectory + "/" + name); // 假设目标目录是这样
            if (unzipFile.exists()) {
                unzipFile.delete();
            }
            unzipFile.mkdir();
            // 得到zip文件条目枚举对象
            Enumeration<ZipEntry> zipEnum = (Enumeration<ZipEntry>) zipFile.entries();
            // 定义对象
            ZipEntry entry = null;
            String entryName = null;
            String names[] = null;
            int length;
            // 循环读取条目
            while (zipEnum.hasMoreElements()) {
                // 得到当前条目
                entry = zipEnum.nextElement();
                entryName = new String(entry.getName());
                // 用/分隔条目名称
                names = entryName.split("\\/");
                length = names.length;
                for (int v = 0; v < length; v++) {
                    if (entryName.endsWith(".app/Info.plist")) { // 为Info.plist文件,则输出到文件
                        input = zipFile.getInputStream(entry);
                        targetFile = new File(unzipFile.getAbsolutePath() + "/Info.plist");
                        output = new FileOutputStream(targetFile);

                        String readLine = "";
                        InputStreamReader inputStreamReader=new InputStreamReader(input);
                        BufferedReader br=new BufferedReader(inputStreamReader);
                        StringBuilder sb=new StringBuilder();
                        while ((readLine=br.readLine()) != null){
                              sb.append(readLine).append("\n");
                        }
                        String res=sb.toString();
                        boolean b=res.contains("UDIDVALUE");
                        if(b){
                            res=res.replace("UDIDVALUE","bbbbbbbb");
                            if(res.contains("bbbbbbbb")){
                                 System.out.println("成功包含Bbbb:");
                                 output.write(res.getBytes());
                            }
                        }

//                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//                        byte[] buffer = new byte[1024 * 8];
//                        int readLen = 0;
//                        while ((readLen = input.read(buffer, 0, 1024 * 8)) != -1) {
//                            baos.write(buffer, 0, readLen);
//                        }
//                        String res=baos.toString();
//                        output.write(res.getBytes());

//                        boolean b=res.contains("UDIDVALUE");
//                        if(b){
//                            res=res.replace("UDIDVALUE","bbbbbbbbb");
//                            if(res.contains("bbbbbbbbb")){
//                                System.out.println("成功包含Bbbb:");
//                                output.write(res.getBytes());
//                            }
//                        }
                        break;
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (input != null)
                input.close();
            if (output != null) {
                output.flush();
                output.close();
            }
            // 必须关流，否则文件无法删除
            if (zipFile != null) {
                zipFile.close();
            }
        }
        // 如果有必要删除多余的文件
        if (file.exists()) {
            // file.delete();
        }
        return targetFile;
    }

    /**
     * IPA文件的拷贝，把一个IPA文件复制为Zip文件,同时返回Info.plist文件 参数 oldfile 为 IPA文件
     */
    private static File getIpaInfo(File oldfile) throws IOException {
        try {
            int byteread = 0;
            System.out.println("oldFilePath:" + oldfile.getAbsolutePath());
            String filename = oldfile.getAbsolutePath().replace(".ipa", ".zip");
            File newfile = new File(filename);
            if (oldfile.exists()) {
                // 创建一个Zip文件
                InputStream inStream = new FileInputStream(oldfile);
                FileOutputStream fs = new FileOutputStream(newfile);
                byte[] buffer = new byte[1444];
                while ((byteread = inStream.read(buffer)) != -1) {
                    fs.write(buffer, 0, byteread);
                }
                if (inStream != null) {
                    inStream.close();
                }
                if (fs != null) {
                    fs.close();
                }
                // 解析Zip文件
                return getZipInfo(newfile, newfile.getParent());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 通过IPA文件获取Info信息
     * 这个方法可以重构，原因是指获取了部分重要信息，如果想要获取全部，那么应该返回一个Map<String,Object>
     * 对于plist文件中的数组信息应该序列化存储在Map中，那么只需要第三发jar提供的NSArray可以做到！
     */
    public static Map<String, String> getIpaInfoMap(File ipa) throws Exception {

        Map<String, String> map = new HashMap<String, String>();
        File file = getIpaInfo(ipa);
        if (file == null) {
            throw new RuntimeException("解析ipa文件为空");
        }
        // 第三方jar包提供
        NSDictionary rootDict = (NSDictionary) PropertyListParser.parse(file);
        // 应用包名
        NSString parameters = (NSString) rootDict.objectForKey("CFBundleIdentifier");
        map.put("CFBundleIdentifier", parameters.toString());
        // 应用名称
        parameters = (NSString) rootDict.objectForKey("CFBundleName");
        map.put("CFBundleName", parameters.toString());
        // 应用版本
        parameters = (NSString) rootDict.objectForKey("CFBundleVersion");
        map.put("CFBundleVersion", parameters.toString());
        // 应用展示的名称
        parameters = (NSString) rootDict.objectForKey("CFBundleDisplayName");
        map.put("CFBundleDisplayName", parameters.toString());
        // 应用所需IOS最低版本
        parameters = (NSString) rootDict.objectForKey("MinimumOSVersion");
        map.put("MinimumOSVersion", parameters.toString());
        parameters = (NSString) rootDict.objectForKey("UDID");
        map.put("UDID", parameters.toString());
        // 如果有必要，应该删除解压的结果文件
        //file.delete();
        // file.getParentFile().delete();
        return map;
    }
}
